﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Tron.DataStructures;
using System.Collections.ObjectModel;
using Microsoft.Xna.Framework;
using Tron.Animations;

namespace Tron.Players
{
    /// <summary>
    /// This class stores the physical state and history of a player.
    /// </summary>
    class PlayerState : IPlayerStatePercepts
    {
        public String Name { get; private set; }
        public Color Color { get; private set; }
        public bool Alive { get; private set; }
        public int PlayerIndex { get; private set; }

        public Vector2 Position { get; private set; }
        public Vector2 Direction { get; private set; }

        List<Move> moves;
        ReadOnlyCollection<Move> readOnlyMoves;

        Board board;

        public Actions Actions { get; private set; }

        public ReadOnlyCollection<Move> Moves
        {
            get
            {
                return readOnlyMoves;
            }
        }

        BlockAnimator blockAnimator;
        public BlockAnimator BlockAnimator
        {
            get
            {
                return blockAnimator;
            }
        }

        public PlayerState(Game game, int playerIndex, Color color, Vector2 startingPosition, 
            Vector2 startingDirection, Board board, String name)
        {
            this.board = board;

            PlayerIndex = playerIndex;
            Color = color;
            Alive = true;
            Name = name;

            moves = new List<Move>();
            readOnlyMoves = new ReadOnlyCollection<Move>(moves);

            Position = startingPosition;
            Direction = startingDirection;

            Actions = new Actions(startingDirection);

            blockAnimator = new BlockAnimator(game, startingPosition);
        }

        public void SetAlive(bool alive)
        {
            Alive = alive;
        }

        public void DoMove()
        {
            Direction = Actions.MoveDirection;
            Vector2 newPosition = Position + Direction;
            if (board.BlockArray[(int)newPosition.X, (int)newPosition.Y] != -2)
                Alive = false;
            Move newMove = new Move(Direction, Position, newPosition);
            moves.Add(newMove);

            Position = newPosition;
        }

        public void DoNextAnimation()
        {
            blockAnimator.Enqueue(new BlockMoveAnimation(blockAnimator, Constants.StepDuration, Position, Position + Actions.MoveDirection));
        }

        public static IPlayerStatePercepts IPlayerStatePerceptsToPlayerState(PlayerState playerState)
        {
            return (IPlayerStatePercepts)playerState;
        }
    }
}
